package com.white.mybatis.dynamic.spring;

import com.white.mybatis.dynamic.DynamicMppaer;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class StateImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 不使用默认的TypeFilter
        ClassPathScanningCandidateComponentProvider provider =
                new ClassPathScanningCandidateComponentProvider(false);
        // 添加扫描规律规则，这里指定了内置的注解过滤规则
        provider.addIncludeFilter(new AnnotationTypeFilter(DynamicMppaer.class));
        // 获取扫描结果的全限定类名
        List<String> className = new ArrayList<>();
        // 扫描指定包，如果有多个包，这个过程可以执行多次
        String[] packages = getPackageToScan(annotationMetadata);
        for (String aPackage : packages) {
            Set<BeanDefinition> beanDefinitionSet = provider.findCandidateComponents(aPackage);
            beanDefinitionSet.forEach(beanDefinition -> className.add(beanDefinition.getBeanClassName()));
        }
        String[] classNameArray = new String[className.size()];
        return className.toArray(classNameArray);
    }

    private String[] getPackageToScan(AnnotationMetadata metadata) {
        //通过自定义注解获取自定义包路径
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(DynamicMapperScan.class.getName()));
        String[] basePackages = attributes.getStringArray("basePackages");
        if (basePackages.length != 0) {
            return basePackages;
        }
        return new String[]{ClassUtils.getPackageName(metadata.getClassName())};
    }
}
